#include <arpa/inet.h>
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <unistd.h>

#define MAX_BUFFER_SIZE 1024

const int requestWaitQueueSize = 5;

void handleError(const char* message)
{
    fputs(message, stderr);
    fputs("\n", stderr);
    exit(1);
}

int main(int argc, char* argv[])
{
    if (argc != 2)
    {
        printf("usage: %s <port>.\n", argv[0]);
        exit(1);
    }

    int serverSocket = socket(PF_INET, SOCK_STREAM, 0);
    if (serverSocket == -1)
    {
        handleError("server socket error");
    }

    struct sockaddr_in serverAddress;
    memset(&serverAddress, 0, sizeof(serverAddress));
    serverAddress.sin_family      = AF_INET;
    serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
    serverAddress.sin_port        = htons(atoi(argv[1]));

    if (bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) == -1)
    {
        handleError("bind() error");
    }

    if (listen(serverSocket, requestWaitQueueSize) == -1)
    {
        handleError("listen() error");
    }

    struct sockaddr_in clientAddress;

    socklen_t clientAddresSize = sizeof(clientAddress);

    char message[MAX_BUFFER_SIZE];
    for (int i = 0; i < requestWaitQueueSize; ++i)
    {
        int clientSocket = accept(serverSocket, (struct sockaddr*)(&clientAddress), &clientAddresSize);
        if (clientSocket == -1)
        {
            handleError("accept() error");
        }
        else
        {
            printf("Connected client %d\n", i + 1);
        }

        while (auto stringLength = read(clientSocket, message, MAX_BUFFER_SIZE))
        {
            write(clientSocket, message, stringLength);
        }
        close(clientSocket);
    }

    close(serverSocket);

    return 0;
}